/**
 * 比较两个字符串，得出匹配结果
 * @param str1
 * @param str2
 * @returns {{arr2: (*|*[]), arr1: (*|*[])}}
 */
function diffStr(str1, str2) {
  let arr1 = _splitStr(str1);
  let arr2 = _splitStr(str2);

  let curStart1 = 0;
  let curStart2 = 0;
  while (curStart1 < arr1.length) {
    let matched = false;
    for (let i = curStart2, l = arr2.length; i < l; i++) {
      if (arr2[i].matchContent === arr1[curStart1].matchContent) {
        arr2[i].type = 0;
        curStart2 = i + 1;
        matched = true;
        break;
      } else {
        arr2[i].type = 1;
      }
    }
    if (!matched) {
      arr1[curStart1].type = -1;
      curStart1++;
    } else {
      arr1[curStart1].type = 0;
      curStart1++;
    }
  }

  // 排除仅顺序变动的情况
  let diffArr1 = _getDiffCellIndexes(arr1);
  let diffArr2 = _getDiffCellIndexes(arr2);

  for (let i1 = 0, l1 = diffArr1.length; i1 < l1; i1++) {
    for (let i2 = 0, l2 = diffArr2.length; i2 < l2; i2++) {
      if (arr1[diffArr1[i1]].matchContent === arr2[diffArr2[i2]].matchContent) {
        arr1[diffArr1[i1]].type = 0;
        diffArr1.splice(i1, 1);
        i1--;
        l1--;

        arr2[diffArr2[i2]].type = 0;
        diffArr2.splice(i2, 1);
        i2--;
        l2--;
        break;
      }
    }
  }

  arr1 = _concatDiff(arr1);
  arr2 = _concatDiff(arr2);

  return {
    arr1: arr1,
    arr2: arr2
  };
}

/**
 * 用正则表达式将字符串拆分
 * @param str
 * @returns arr
 */
function _splitStr(str) {
  let matchRegx =
    /((\d{4}[-/年]{0,1}\d{1,2}[-/月]{0,1}\d{1,2}日{0,1})|([+-]{0,1}\d+(.\d+){0,1})|[A-Za-z]+|[*]+|[\u4e00-\u9fa5]+)[^\dA-Za-z*\u4e00-\u9fa5]*/g;
  let arr = str.match(matchRegx) || [];
  for (let i = 0, l = arr.length; i < l; i++) {
    arr[i] = {
      index: i,
      content: arr[i],
      matchContent: arr[i].match(
        /((\d{4}[-/年]{0,1}\d{1,2}[-/月]{0,1}\d{1,2}日{0,1})|([+-]{0,1}\d+(.\d+){0,1})|[A-Za-z]+|[*]+|[\u4e00-\u9fa5]+)/g
      )[0],
      mergeAble:
        !/((\d{4}[-/年]{0,1}\d{1,2}[-/月]{0,1}\d{1,2}日{0,1})|([+-]{0,1}\d+(.\d+){0,1})|[A-Za-z]+|[*]+)[^\dA-Za-z*\u4e00-\u9fa5]*/.test(
          arr[i]
        )
    };
  }

  return arr;
}

/**
 * 获取数组中未能匹配上的子串索引
 * @param arr
 * @return {*[]}
 */
function _getDiffCellIndexes(arr) {
  let result = [];
  for (let i = 0, l = arr.length; i < l; i++) {
    if (arr[i].type !== 0) {
      result.push(i);
    }
  }
  return result;
}

/**
 * 将相邻的不同子串合并
 * @param arr
 * @return {*}
 */
function _concatDiff(arr) {
  let mergeAble = false;
  for (let i = 1, l = arr.length; i < l; i++) {
    if (arr[i].type !== 0 && arr[i - 1].type === arr[i].type) {
      mergeAble = arr[i].mergeAble && arr[i - 1].mergeAble;
    } else {
      mergeAble = false;
    }
    if (mergeAble) {
      arr[i - 1].content += arr[i].content;
      arr.splice(i, 1);
      i--;
      l--;
    }
  }
  return arr;
}

export default {
  diffStr
};
